package es.deusto.ingenieria.is.Hanoi.formulation;

import java.util.ArrayList;
import java.util.Stack;
import es.deusto.ingenieria.is.search.formulation.Operator;
import es.deusto.ingenieria.is.search.formulation.State;

public class Mover_Disco extends Operator{

	private Soporte soporteOrigen;
	private Soporte soporteDestino;
	
	public Mover_Disco(Soporte soporteOrigen, Soporte soporteDestino) {
		this.soporteDestino=soporteDestino;
		this.soporteOrigen=soporteOrigen;
		this.setName("Mover de "+this.soporteOrigen.getPosicion()+" a "+this.soporteDestino.getPosicion());
	}
	
	protected boolean isApplicable(State state) {
		Estado_Hanoi estado=(Estado_Hanoi)state;
		int sopOrigen=this.soporteOrigen.getPosicion()-1;
		int sopDestino=this.soporteDestino.getPosicion()-1;
		
		Soporte soporteOrigen = estado.getSoporteIndex(sopOrigen);
		Soporte soporteDestino = estado.getSoporteIndex(sopDestino);
		
		
		if(soporteOrigen.getlDiscos().isEmpty())
			return false;
		else{
			if(soporteDestino.getlDiscos().isEmpty())
				return true;
			else{
				Disco dOrigen=soporteOrigen.getlDiscos().pop();
				Disco dDestino=soporteDestino.getlDiscos().pop();
				if(dOrigen.getTamanyo() < dDestino.getTamanyo()){
					soporteOrigen.getlDiscos().push(dOrigen);
					soporteDestino.getlDiscos().push(dDestino);
					return true;
				}else{
					soporteOrigen.getlDiscos().push(dOrigen);
					soporteDestino.getlDiscos().push(dDestino);
					return false;
				}
			}
		}
	}
	
	protected State effect(State state) {
		Estado_Hanoi estado=(Estado_Hanoi)((Estado_Hanoi)state).clone();
		int sopOrigen=this.soporteOrigen.getPosicion()-1;
		int sopDestino=this.soporteDestino.getPosicion()-1;
		ArrayList<Soporte> ls=estado.getSoportes();
		Stack<Disco> lo=ls.get(sopOrigen).getlDiscos();
		Stack<Disco> ld=ls.get(sopDestino).getlDiscos();
		
		Disco dOrigen=lo.pop();
		ls.get(sopOrigen).setnDiscos(estado.getSoportes().get(sopOrigen).getnDiscos()-1);
		
		ld.push(dOrigen);
		ls.get(sopDestino).setnDiscos(estado.getSoportes().get(sopDestino).getnDiscos()+1);
		
		ls.get(sopOrigen).setlDiscos(lo);
		ls.get(sopDestino).setlDiscos(ld);
		estado.setSoportes(ls);
		
		
		return estado;
		
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}


}
